package exquery

import exquery.annotations.Queryable
import exquery.util.SearchHelper
import exquery.util.ValidationUtil
import org.apache.log4j.Logger
import setupx.entity.*
import exquery.valuebeans.export.SpeciesVO
import exquery.valuebeans.export.OrganVO
import exquery.valuebeans.export.UserVO

class SearchService {

    Logger gLogger = Logger.getLogger(SearchService.class)
    boolean transactional = true
    def grailsApplication
    def setting

    void afterPropertiesSet() { this.setting = grailsApplication.config.setting }

    SearchHelper helper = SearchHelper.getInstance()
    LookupService lookupService
    def experimentService

    /**
     * constructor which initializes the mapping of compounds
     */
    public SearchService() {

    }

    def search(def searchBy, def searchText, Map params = [:]) {

      gLogger.info "Comming into search method of SearchService"
      gLogger.info "helper :: ${helper}"

      //get the search method name
      String searchMethod = helper.getSearchMethodName(searchBy)
      gLogger.info "searchMethod :: ${searchMethod}"

      def result
      //make sure we actually know the mapping
      if (searchMethod == null) {
        result = ["ErrorMsg" : "wrong search criteria, ${searchBy}"]
      }else{
         result = "$searchMethod"(searchText, params)
         gLogger.info "result :: ${result}"
         if( result == null || result?.result!=null || result?.result?.size() == 0 ||
              result?.TotalRecordCount ==null || Long.parseLong(result?.TotalRecordCount.toString()) == (long)0){
           result.putAt "ErrorMsg","No Data Found..."
         }
      }

      return result;
    }

  /**
   * Search into experiments
   */
  @Queryable(name = "Experiments")
  def searchExperiments(def searchText, Map params = [:]) {
    gLogger.info "comming into searchExperiments method of SearchService"
    def result = null;
    def isPaginate = false
    def isExport = true
    long recCount = 0
    if( ValidationUtil.getInstance().isLong(searchText.toString())){
        Long id = Long.parseLong(searchText.toString())
        Experiment e = lookupService.searchExperimentById(id)
        result = new ArrayList<Experiment>()
        if(e!=null){
          result.add(e)
        }
        recCount = result.size()
        isExport = true
    } else if(searchText instanceof String){
//        if( searchText.toString().trim().equals("*")){
//          result = lookupService.getAllExperiments();
//          recCount = result.size
//          isExport = true
//        }else{
          result = lookupService.searchExperiments(searchText,params);
          recCount = lookupService.searchExperimentsCount(searchText);
          isPaginate = true
//        }
    }
    gLogger.info "out from searchExperiments method of SearchService"
    return ["result":result,"isPaginate":isPaginate,"TotalRecordCount":recCount,"isExport":isExport]
  }

  /**
   * Search into classes
   */
  @Queryable(name = "Classes")
  def searchClasses(def searchText, Map params = [:]) {
    gLogger.info "comming into searchClasses method of SearchService"
    def result = null;
    def isPaginate = false
    def isExport = false
    long recCount = 0
    if( ValidationUtil.getInstance().isLong(searchText.toString())){
        Long id = Long.parseLong(searchText.toString())
        ExperimentClass e = lookupService.searchExperimentClassById(id)
        result = new ArrayList<ExperimentClass>()
        if(e!=null){
          result.add(e)
        }
        recCount = result.size()
        isExport = true
    } else if(searchText instanceof String){
//        if( searchText.toString().trim().equals("*")){
//          result = lookupService.getAllExperimentClasses();
//          recCount = result.size
//          isExport = true
//        }else{
          result = lookupService.searchExperimentClasses(searchText,params);
          recCount = lookupService.searchExperimentClassesCount(searchText);
          isPaginate = true
//        }
    }
    gLogger.info "out from searchClasses method of SearchService"
    return ["result":result,"isPaginate":isPaginate,"TotalRecordCount":recCount,"isExport":isExport]
  }

  /**
   * Search into samples
   */
  @Queryable(name = "Samples")
  def searchSamples(def searchText, Map params = [:]) {
    gLogger.info "comming into searchSamples method of SearchService"
    def result = null;
    def isPaginate = false
    def isExport = false
    long recCount = 0
    if( ValidationUtil.getInstance().isLong(searchText.toString())){
        Long id = Long.parseLong(searchText.toString())
        ClassSample s = lookupService.searchSampleById(id)
        result = new ArrayList<ClassSample>()
        if(s!=null){
          result.add(s)
        }
        recCount = result.size()
        isExport = true
    } else if(searchText instanceof String){
//        if( searchText.toString().trim().equals("*")){
//          result = lookupService.getAllSamples();
//          recCount = result.size
//          isExport = true
//        }else{
          result = lookupService.searchSamples(searchText,params);
          recCount = lookupService.searchSamplesCount(searchText);
          isPaginate = true
//        }
    }
    gLogger.info "out from searchSamples method of SearchService"
    return ["result":result,"isPaginate":isPaginate,"TotalRecordCount":recCount,"isExport":isExport]
  }

  /**
   * Search into species
   */
  @Queryable(name = "Species")
  def searchSpecies(def searchText, Map params = [:]) {
    gLogger.info "comming into searchSpecies method of SearchService"
    def result = null;
    def isPaginate = false
    def isExport = true
    long recCount = 0
    if( ValidationUtil.getInstance().isLong(searchText.toString())){
        Long id = Long.parseLong(searchText.toString())
        SpeciesVO s = lookupService.searchSpeciesById(id)
        result = new ArrayList<SpeciesVO>()
        if(s!=null){
          result.add(s)
        }
        recCount = result.size()
    } else if(searchText instanceof String){
        if( searchText.split("[*]").size()==0){
          result = lookupService.getAllSpecies();
          recCount = result.size
        }else{
          result = lookupService.searchSpecies(searchText);
          //lookupService.searchSpeciesCount(searchText);
          if(result!=null){
            recCount = result.size()
          }
          //isPaginate = true
        }
    }
    gLogger.info "out from searchSpecies method of SearchService"
    return ["result":result,"isPaginate":isPaginate,"TotalRecordCount":recCount,"isExport":isExport]
  }

  /**
   * Search into organs
   */
  @Queryable(name = "Organs")
  def searchOrgans(def searchText, Map params = [:]) {
    gLogger.info "comming into searchOrgans method of SearchService"
    def result = null;
    def isPaginate = false
    def isExport = true
    long recCount = 0
    if( ValidationUtil.getInstance().isLong(searchText.toString())){
        Long id = Long.parseLong(searchText.toString())
        OrganVO organVO = lookupService.searchOrganById(id)
        result = new ArrayList<OrganVO>()
        if(organVO!=null){
          result.add(organVO)
        }
        recCount = result.size()
    } else if(searchText instanceof String){
        if(searchText.split("[*]").size()==0){
          result = lookupService.getAllOrgans();
          recCount = result.size
        }else{
          result = lookupService.searchOrgans(searchText);
          //recCount = lookupService.searchOrgansCount(searchText);
          if(result!=null){
            recCount = result.size()
          }
          //isPaginate = true
        }
    }
    gLogger.info "out from searchOrgans method of SearchService"
    return ["result":result,"isPaginate":isPaginate,"TotalRecordCount":recCount,"isExport":isExport]
  }

  /**
   * Search into user
   */
  @Queryable(name = "User")
  def searchUsers(def searchText, Map params = [:]) {
    gLogger.info "comming into searchUsers method of SearchService"
    def result = null;
    def isPaginate = false
    def isExport = true
    long recCount = 0
    if( ValidationUtil.getInstance().isLong(searchText.toString())){
        Long id = Long.parseLong(searchText.toString())
        UserVO userVO = lookupService.searchUserById(id)

        result = new ArrayList<UserVO>()
        if(userVO!=null){
          result.add(userVO)
        }
        if(result!=null){
          recCount = result.size()
        }
    } else if(searchText instanceof String){
        if( searchText.split("[*]").size()==0){
          result = lookupService.getAllUsers();
          recCount = result.size
        }else{
          result = lookupService.searchUser(searchText);
          if(result!=null){
            recCount = result.size()
          }
        }
    }

    if(result!=null && result.size()>0){
      result = result.sort{it.samplesCount}.reverse()
    }

    gLogger.info "out from searchUsers method of SearchService"
    return ["result":result,"isPaginate":isPaginate,"TotalRecordCount":recCount,"isExport":isExport]
  }

  /**
   * Search All
   */
  @Queryable(name = "SearchAll")
  def searchAll(def searchText, Map params = [:]) {
    gLogger.info "comming into searchAll method of SearchService"
    def result = []
    def isPaginate = false
    def isExport = false
    long recCount = 0
    def tempResult

    //Search Into Experiments
    tempResult = searchExperiments(searchText)
    if(tempResult!=null && tempResult.result!=null && tempResult?.TotalRecordCount>0){
        tempResult.result.each {data->
            result.add(data)
        }
    }

    //Search Into ExperimentClasses
    tempResult = searchClasses(searchText)
    if(tempResult!=null && tempResult.result!=null && tempResult?.TotalRecordCount>0){
        tempResult.result.each {data->
            result.add(data)
        }
    }

    //Search Into ClassSample
    tempResult = searchSamples(searchText)
    if(tempResult!=null && tempResult.result!=null && tempResult?.TotalRecordCount>0){
        tempResult.result.each {data->
            result.add(data)
        }
    }

    //Search Into ClassSpecies
    tempResult = searchSpecies(searchText)
    if(tempResult!=null && tempResult.result!=null && tempResult?.TotalRecordCount>0){
        tempResult.result.each {data->
            result.add(data)
        }
    }

    //Search Into ClassOrgans
    tempResult = searchOrgans(searchText)
    if(tempResult!=null && tempResult.result!=null && tempResult?.TotalRecordCount>0){
        tempResult.result.each {data->
            result.add(data)
        }
    }

    //Search Into User
    tempResult = searchUsers(searchText)
    if(tempResult!=null && tempResult.result!=null && tempResult?.TotalRecordCount>0){
        tempResult.result.each {data->
            result.add(data)
        }
    }

    if(result!=null){
        recCount = result?.size()
    }

    gLogger.info "result :: ${result}"

    gLogger.info "out from searchAll method of SearchService"
    return ["result":result,"isPaginate":isPaginate,"TotalRecordCount":recCount,"isExport":isExport]
  }

}
